package com.nazca.tvremote.service;

import com.nazca.tvremote.service.IEventService;
import com.nazca.tvremote.service.IEventServiceCallback;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;

public class EventServiceProxy implements IEventService {

//	private static final String TAG = "EventServiceProxy";
	
	private final Context mContext;
    private final Class<?> mClass;
	private IEventService mService = null;
	private Runnable mRunnable;
	private final IEventServiceCallback mCallback;
	
	private EventServiceConnection mEventServiceConnection = new EventServiceConnection();
	
	private boolean mDead = false;
	
	public EventServiceProxy(Context _context, Class<?> _class, IEventServiceCallback _callback) {
//		Log.d(TAG, "EventServiceProxy()");
//		Log.d(TAG, "_callback:" + _callback);
        mContext = _context;
        mClass = _class;
        mCallback = _callback;
        // Proxy calls have a timeout, and this can cause failures while debugging due to the
        // far slower execution speed.  In particular, validate calls fail regularly with ssl
        // connections at the default timeout (30 seconds)
    }
	
	
	@Override
	public void connectToServer(final String dstAddress, final int dstPort)
			throws RemoteException {
		setTask(new Runnable () {
            public void run() {
                try {
                    if (mCallback != null) mService.setCallback(mCallback);
                    mService.connectToServer(dstAddress, dstPort);
                } catch (RemoteException e) {
                }
            }
        });
	}

	@Override
	public void disConnectToServer() throws RemoteException {
		setTask(new Runnable () {
            public void run() {
                try {
                    if (mCallback != null) mService.setCallback(mCallback);
                    mService.disConnectToServer();
                } catch (RemoteException e) {
                }
            }
        });
	}

	@Override
	public void println(final String line) throws RemoteException {
		setTask(new Runnable () {
            public void run() {
                try {
                    if (mCallback != null) mService.setCallback(mCallback);
                    mService.println(line);
                } catch (RemoteException e) {
                }
            }
        });
	}

	@Override
	public void setCallback(final IEventServiceCallback cb) throws RemoteException {
		setTask(new Runnable () {
            public void run() {
                try {
                    mService.setCallback(cb);
                } catch (RemoteException e) {
                }
            }
        });
	}

	@Override
	public IBinder asBinder() {
		return null;
	}

	
	class EventServiceConnection implements ServiceConnection{
        public void onServiceConnected(ComponentName className,
                IBinder service) {
            mService = IEventService.Stub.asInterface(service);
            
            new Thread(new Runnable() {
                public void run() {
                    runTask();
                }}).start();
            
        }

        public void onServiceDisconnected(ComponentName className) {
            mService = null;
        }
    };
    
    private void runTask() {
        Thread thread = new Thread(mRunnable);
        thread.start();
        try {
            thread.join();
        } catch (InterruptedException e) {
        }

        try {
            mContext.unbindService(mEventServiceConnection);
        } catch (IllegalArgumentException e) {
            // This can happen if the user ended the activity that was using the service
            // This is harmless, but we've got to catch it
        }

        mDead = true;
        synchronized(mEventServiceConnection) {
        	mEventServiceConnection.notify();
        }
    }

    private void setTask(Runnable runnable) throws RemoteException {
        if (mDead) {
            throw new RemoteException();
        }
        mRunnable = runnable;
        mContext.bindService(new Intent(mContext, mClass), mEventServiceConnection,
                Context.BIND_AUTO_CREATE);
//        new Thread(new Runnable() {
//            public void run() {
//                runTask();
//            }}).start();
    }
    
//    //**************************************
//    //�Ժ�ĳ�ÿ��Activityֻbindsһ��
//    //**************************************
//    public void bindService(){
//    	mContext.startService(new Intent(mContext, EventService.class));
//    	mContext.bindService(new Intent(mContext, EventService.class), mEventServiceConnection,
//                Context.BIND_AUTO_CREATE);
//    }
//    public void unBindService(){
//    	try {
//    		mContext.unbindService(mEventServiceConnection);
//        } catch (IllegalArgumentException e) {
//            // This can happen if the user ended the activity that was using the service
//            // This is harmless, but we've got to catch it
//        }
//    }
}
